package com.itheima.marking_system.controller;


import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.marking_system.pojo.common.request.*;
import com.itheima.marking_system.pojo.common.R;

import com.itheima.marking_system.pojo.entity.*;
import com.itheima.marking_system.service.*;
import com.itheima.marking_system.utils.aliyun.QianWenChat;
import com.itheima.marking_system.utils.baidu.BaiduUtils;
import com.itheima.marking_system.utils.baidu.BigModelNew;
import com.itheima.marking_system.utils.baidu.Model;
import com.itheima.marking_system.utils.zip.screen.ScreenUtils;
import com.itheima.marking_system.utils.zip.ZipUtils;
import com.itheima.marking_system.utils.zip.unzip.UnzipUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import kotlin.Pair;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/common")
@Slf4j
@Api(tags = "【公共】")

public class CommonController {

    @Autowired
    private ChatService chatService;

    @Autowired
    private PictureService pictureService;

    @Autowired
    private RegionService regionService;

    @Autowired
    private OcrService ocrService;

    @Autowired
    private ZipService zipService;

    @Autowired
    private ElementService elementService;


    //定义一个上传文件的接口，接收前端传来的文件参数
//    @PostMapping("/upload")
//    public R<String> upload(@RequestParam MultipartFile file) {
//        //TODO: 上传文件接口，需要将前端传来的文件保存到数据库中，并返回文件ID,这里上传二进制数组可以避免文件上传格式限制，不过前端是需要提示只能上传zip文件
//        //调用pictureService中的toFile方法将MultipartFile类型的文件转换为File类型
//        File tempFile = ZipUtils.toFile(file);
//        //调用pictureService中的setBytes方法将转换后的文件转换为字节数组
//        byte[] bytes = ZipUtils.setBytes(tempFile);
//        //新建一个PictureEntity对象，用于保存文件信息
//        PictureEntity pictureEntity = new PictureEntity();
//        //设置PictureEntity对象的data属性为转换后的字节数组
//        pictureEntity.setData(bytes);
//        //设置PictureEntity对象的name属性为原始文件名
//        pictureEntity.setName(file.getOriginalFilename());
//        //调用pictureService中的save方法将PictureEntity对象保存到数据库中
//        pictureEntity.setId((long) (pictureService.count() + 1));
//        pictureService.save(pictureEntity);
//        //返回成功消息
//        return R.success("上传成功");
//    }

    @ApiOperation(value = "上传zip文件接口", notes = "该接口用于上传zip文件")
    @PostMapping("/upload_zip")
    @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = MultipartFile.class, required = true)
    public R<String> upload_zip(@RequestParam MultipartFile file) {
        //TODO: 上传文件接口，需要将前端传来的文件保存到数据库中，并返回文件ID,这里上传二进制数组可以避免文件上传格式限制，不过前端是需要提示只能上传zip文件
        //调用pictureService中的toFile方法将MultipartFile类型的文件转换为File类型
        File tempFile = ZipUtils.toFile(file);
        //调用pictureService中的setBytes方法将转换后的文件转换为字节数组
        byte[] bytes = ZipUtils.setBytes(tempFile);
        ZipEntity zipEntity = new ZipEntity();
        zipEntity.setName(file.getOriginalFilename());
        zipEntity.setData(bytes);
        zipService.save(zipEntity);
        //返回成功消息
        return R.success("上传成功");
    }
//    // 下载文件接口
//    @PostMapping("/download")
//    public R<String> download(@RequestBody PictureRequset pictureRequset) {
//        //TODO: 下载文件接口，需要根据前端传来的id字段查询数据库，然后将文件保存到指定路径,这里需要完善
//        // 创建查询条件包装器
//        LambdaQueryWrapper<PictureEntity> queryWrapper = new LambdaQueryWrapper<>();
//        // 根据请求中的id字段进行查询
//        queryWrapper.eq(PictureEntity::getId, pictureRequset.getId());
//        // 查询数据库获取图片实体
//        PictureEntity pictureEntity = pictureService.getOne(queryWrapper);
//        // 如果图片实体为空，返回错误信息
//        if (pictureEntity == null) {
//            return R.error("文件不存在");
//        }
//        // 将文件保存到指定路径
//        try {
//            ZipUtils.writeBytes(pictureEntity.getData(), pictureRequset.getFilePath());
//            return R.success("文件下载成功");
//        } catch (IOException e) {
//            log.error("文件下载失败", e);
//            return R.error("文件下载失败");
//        }
//    }


    @ApiOperation(value = "截图接口", notes = " 该接口用于截图")
    @PostMapping("/screen") // 定义一个POST类型的HTTP请求映射，路径为"/screen"

    public R<String> screen(@RequestBody ScreenRequest regionRequest) {
        Long templateId = regionRequest.getTemplateId();
        List<PictureEntity> pictureEntities = pictureService.getPictureList(regionRequest.getZipId());
        List<RegionEntity> regionEntities = regionService.getRegionList(templateId);
        for (PictureEntity pictureEntity : pictureEntities) {
            for (RegionEntity region : regionEntities) {
                // 获取图片宽高
                int width = 0;
                int height = 0;
                try {
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(pictureEntity.getData());
                    BufferedImage image = ImageIO.read(inputStream);
                    width = image.getWidth();
                    height = image.getHeight();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                // 判断尺寸是否大于图片本身
                if (region.getWidth() > width || region.getHeight() > height) {
                    // 如果尺寸大于图片本身，直接保存到ElementEntity里面
                    ElementEntity elementEntity = new ElementEntity();
                    elementEntity.setData(pictureEntity.getData());
                    elementEntity.setName(pictureEntity.getName());
                    elementEntity.setPictureId(pictureEntity.getId());
                    elementService.save(elementEntity);
                    System.out.println("选区尺寸大于图片尺寸，保存成功");
                } else {
                    // 否则进行截图并保存到ElementEntity里面
                    ElementEntity elementEntity = ScreenUtils.captureScreen(pictureEntity.getData(), pictureEntity.getName(), region);
                    elementEntity.setPictureId(pictureEntity.getId());
                    elementService.save(elementEntity);
                    System.out.println("选区尺寸小于图片尺寸，保存成功");
                }
            }
        }
        return R.success("截图成功");
    }


    @ApiModelProperty(value = "解压zip文件接口", notes = "该接口用于解压文件")
    @PostMapping("/unzip")
    public R<String> unzip(@RequestBody UnzipRequest unzipRequest) {

        //TODO: 解压文件接口，需要将前端传来的zip文件id解压，并保存到picture数据库中，这里使用元组键值对返回解压后的文件信息，设置zipId为前端传来的zipFileId
        LambdaQueryWrapper<ZipEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZipEntity::getId, unzipRequest.getZipFileId());
        ZipEntity zipEntity = zipService.getOne(queryWrapper);
        if (zipEntity == null) {
            return R.error("文件不存在");
        }

        Pair<List<String>, List<byte[]>> result= null;
        try{
            //TODO: 调用UnzipUtils中的unzip方法解压zip文件，并保存到picture数据库中,这里采用元组键值对返回解压后的文件信息
            result = UnzipUtils.unzip(zipEntity);
            for (int i = 0; i < result.getFirst().size(); i++) {
                PictureEntity pictureEntity = new PictureEntity();
                pictureEntity.setName(result.getFirst().get(i));
                pictureEntity.setData(result.getSecond().get(i));
                pictureEntity.setZipId(zipEntity.getId());
                pictureService.save(pictureEntity);
            }
            return R.success("解压成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
//
//
//    @ApiModelProperty(value = "识别图片接口", notes = "该接口用于识别图片")
//    @PostMapping("/ocr")
//    //后续需要修改
//    public R<String> ocr(@RequestBody OcrRequest ocrRequest) {
////        for (Long elementId : ocrRequest.getElementIds()) {
////            LambdaQueryWrapper<ElementEntity> elementQueryWrapper = new LambdaQueryWrapper<>();
////            elementQueryWrapper.eq(ElementEntity::getId, elementId);
////            ElementEntity elementResult = elementService.getOne(elementQueryWrapper);
////            if (elementResult == null) {
////                return R.error("元素不存在");
////            }
//        LambdaQueryWrapper<PictureEntity> pictureQueryWrapper = new LambdaQueryWrapper<>();
//        pictureQueryWrapper.eq(PictureEntity::getId, ocrRequest.getElementId());
//        PictureEntity pictureResult = pictureService.getOne(pictureQueryWrapper);
//        if (pictureResult == null) {
//            return R.error("图片不存在");
//        }
//        byte[] bytes = BaiduUtils.getOcrResult(pictureResult.getData()).getBytes();
//        OcrEntity ocrEntity = new OcrEntity();
//        ocrEntity.setId((long) (ocrService.count() + 1));
//        ocrEntity.setData(bytes);
////            ocrEntity.setElementId(elementId);
//        ocrService.save(ocrEntity);
////        }
//        return R.success("识别成功");
//    }


    @ApiOperation(value = "大模型回复接口", notes = "该接口用于大模型回复")
    @GetMapping("/xinghuo")
    @ApiImplicitParam(name = "zipId", value = "zipId", dataTypeClass = String.class, required = true)
    public R<Pair<List<String>, List<String>>> elementList(PictureListRequest pictureListRequest) throws Exception {
        //TODO: 获取图片列表接口，需要根据前端传来的pictureId列表查询数据库element表，并且进行识别，将识别后的结果保存到数据库ocr中

        List<ElementEntity> elementEntities = elementService.getElementList(pictureListRequest.getZipId());


        List<String> AnswerList = new ArrayList<>();
        List<String> QuestionList = new ArrayList<>();
        for (ElementEntity elementEntity : elementEntities) {

            Pair<OcrEntity, String> ocrPair = ocrService.setOcrEntity(elementEntity);
            //TODO: 调用模型接口，传入图片数据，返回模型输出结果

            OcrEntity ocrEntity = ocrPair.getFirst();
            String question = ocrPair.getSecond();
            BigModelNew.main(question);
            //等待模型输出结果
            ocrEntity.setAnswer(BigModelNew.Answer.getBytes());
            AnswerList.add(BigModelNew.totalAnswer);
            QuestionList.add(question);
            ocrService.save(ocrEntity);

        }
        return getPairR(AnswerList, QuestionList);
    }




    @RequestMapping("/chat")
    public R<Pair<List<String>, List<String>>> chatAi(PictureListRequest pictureListRequest) throws NoApiKeyException, InputRequiredException {
        String role = "假如你是老师，我是学生，请你帮我看一下这张图片，先给出答案，然后再给出解析，要求清晰易懂。";

        List<ElementEntity> elementEntities = elementService.getElementList(pictureListRequest.getZipId());


        List<String> AnswerList = new ArrayList<>();
        List<String> QuestionList = new ArrayList<>();
        for (ElementEntity elementEntity : elementEntities) {

            Pair<OcrEntity, String> ocrPair = ocrService.setOcrEntity(elementEntity);
            //TODO: 调用模型接口，传入图片数据，返回模型输出结果

            OcrEntity ocrEntity = ocrPair.getFirst();
            String question = ocrPair.getSecond();
            //等待模型输出结果
            ocrEntity.setAnswer(chatService.chatAi(role,question).getBytes());
            AnswerList.add(chatService.chatAi(role,question).replace("GenerationOutput.Choice(finishReason=stop, message=Message(role=assistant, content=","").replace("))",""));
            QuestionList.add(question);
            ocrService.save(ocrEntity);

        }
        return getPairR(AnswerList, QuestionList);
    }

    @NotNull
    private R<Pair<List<String>, List<String>>> getPairR(List<String> answerList, List<String> questionList) {
        Pair<List<String>, List<String>> result = new Pair<>(answerList, questionList);
        for (int i = 0; i < result.getFirst().size(); i++) {
            System.out.println(result.getFirst().get(i)   + "\n" + result.getSecond().get(i));
        }
        return R.success(result);
    }




}
